package com.msmall.community.common.service.impl;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.msmall.base.pager.MatchType;
import com.msmall.base.service.impl.BaseManagerImpl;
import com.msmall.community.common.dao.CityDao;
import com.msmall.community.common.model.City;
import com.msmall.community.common.service.CityManager;

public class CityManagerImpl extends BaseManagerImpl<City, String> implements CityManager{

	private static final Log log = LogFactory.getLog(CityManagerImpl.class);
	
	private CityDao cityDao;
	
	public void setCityDao(CityDao cityDao) {
		this.cityDao = cityDao;
	}
	/**
	 * 通过区划码获得直接子级的所有城市
	 * 需要判断当前区域所在级别， 1级获得2级， 2级获得3级， 如果是直辖市直接由1级获得3级
	 * @param code 110000
	 * @return
	 * @throws Exception
	 */
	public List<City> getChildCities(String code) throws Exception {
		int level = getLevel(code);
		boolean direct = isDirect(code);
		return cityDao.getChildCities(code, direct, level);
	}
	/**
	 * 通过区划码获得直接子级的所有城市
	 * 需要判断当前区域所在级别， 1级获得2级， 2级获得3级， 如果是直辖市直接由1级获得3级
	 * 作为天气使用，如果数据库没有weather_code 值，则过滤掉
	 * @param code 110000
	 * @return
	 * @throws Exception
	 */
	public List<City> getWeatherChildCities(String code) throws Exception{
		int level = getLevel(code);
		boolean direct = isDirect(code);
		return cityDao.getWeatherChildCities(code, direct, level);
	}
	/**
	 * 通过区划码获得。例如110000获得北京记录
	 * @param code
	 * @return
	 * @throws Exception
	 */
	public City getCityByCode(String code) throws Exception {
		try{
			List list = cityDao.getByProperty(City.class, "cityCode", MatchType.EQ, code);
			if(list != null && list.size() > 0)
				return (City) list.get(0);
			return null;
		}catch(Exception e){
			throw new Exception("City not found with code : "+ code);
		}
	}
	/**
	 * 通过汉语拼音获得,例如:beijing
	 * @param code
	 * @throws Exception 
	 */
	public City getCityByEnglishName(String name) throws Exception {
		List list = cityDao.getByProperty(City.class, "englishName", MatchType.EQ, name);
		if(list != null && list.size() > 0)
			return (City) list.get(0);
		throw new Exception("City not found with EnglishName : "+ name);
	}
	/**
	 * 通过中文名称获得,例如：北京;河北;没有等级名称
	 * @param name
	 * @throws Exception 
	 */
	public City getCityByName(String name) throws Exception {
		List list = cityDao.getByProperty(City.class, "cityName", MatchType.LIKE, name);
		if(list != null && list.size() > 0)
			return (City) list.get(0);
		throw new Exception("City not found with name : "+ name);
	}
	/**
	 * 通过天气的拼音查询,例如:beijing
	 */
	public City getCityByWeatherCode(String code) throws Exception {
		List list = cityDao.getByProperty(City.class, "weatherCode", MatchType.EQ, code);
		if(list != null && list.size() > 0)
			return (City) list.get(0);
		throw new Exception("City not found with WeatherCode : "+ code);
	}
	/**
	 * 获得所有最高级别的区域信息，直辖市和省
	 * @return
	 */
	public List<City> getTopCities() throws Exception {
		return cityDao.getTopCities();
	}
	/**
	 * 获得同一个父级别下的所有子级别
	 * 例如：code=浦东新区；返回上海的所有区
	 * @return
	 */
	public List<City> getSameParentCities(String code) throws Exception{
		String parentCode = getUpCode(code);
		return getChildCities(parentCode);
	}
	/**
	 * 通过行政区划码获得此地区的级别， 共三级别；
	 * 后四位都为0第一级别（最高级），返回1；
	 * 后2位为0，第二级别，返回2
	 * 否则，第三级别，返回3
	 * @param code
	 * @return
	 */
	public int getLevel(String code) throws Exception{
		if(!isCode(code)){
			throw new Exception("code is not correct : " + code);
		}
		String middle = code.substring(2,4);
		String last = code.substring(4,6);
		int middlei = Integer.valueOf(middle);
		int lasti = Integer.valueOf(last);
		if(middlei == 0 && lasti == 0)return 1;
		if(lasti == 0) return 2;
		return 3;
	}
	/**
	 * 获得上一级别的CODE 
	 * EG：360802获得 360800； 360800获得360000
	 * @param code
	 * @return
	 * @throws Exception
	 */
	public String getUpCode(String code) throws Exception{
		int level = getLevel(code);
		if(level == 3){
			return code.substring(0,4) + "00";
		}else if(level == 2){
			return code.substring(0, 2) + "0000";
		}else{
			return code;
		}
	}
	
	/**
	 * 获得上一级别的区域
	 * EG：360802获得 360800； 360800获得360000
	 * 如果是直辖市需要由level=3，直接获得level=1的城市；110101获得110000
	 * @param code
	 * @return
	 * @throws Exception
	 */
	public City getUpCity(String code) throws Exception{
		String upcode = getUpCode(code);
		if(upcode.equals(code)){//已经是最高级别区域
			return null;
		}
		City city;
		city = this.getCityByCode(upcode);
		if(city == null){
			upcode = getUpCode(upcode); //直辖市时
			city = this.getCityByCode(upcode);
		}
		return city;
	}
	/**
	 * 判断是不是有效的地区区域码
	 * @param code
	 * @return
	 */
	public boolean isCode(String code){
		if(!StringUtils.isNumeric(code) || code.length() != 6){
			log.error("code is not correct : " + code);
			return false;
		}
		return true;
	}
	/**
	 * 判断是不是直辖市
	 */
	public boolean isDirect(String code){
		String direct = "110000,120000,310000,500000";
		if(direct.indexOf(code) != -1)
			return true;
		return false;
		
	}
}
